package com.hnit.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hnit.mapper.OrdersMapper;
import com.hnit.mapper.ProductMapper;
import com.hnit.mapper.UserCouponsMapper;
import com.hnit.service.*;
import com.hnit.web.Clients.IdServiceClient;
import com.hnit.web.DTO.OrdersDTO;
import com.hnit.web.DTO.OrdersItemsDTO;
import com.hnit.web.DTO.ProductDTO;
import com.hnit.web.Utils.OrderStatus;
import com.hnit.web.Utils.ResponseResult;
import com.hnit.web.bean.OrderItems;
import com.hnit.web.bean.Orders;
import com.hnit.web.bean.Product;
import com.hnit.web.bean.UserCoupons;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrdersService {

    @Autowired
    private IdServiceClient idGeneratorApi;

    // 假设你有一个 OrderItemsService 用于操作订单项
    @Autowired
    private OrdersItemsService ordersItemsService;
    @Autowired
    private CartService cartService;

    @Autowired
    private OrdersItemsService orderItemsService; // 订单明细服务

    @Autowired
    private ProductService productService; // 商品服务

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private AddressService addressService;
    @Autowired
    private UserCouponsMapper userCouponsMapper;
    @Autowired
    private  CouponService couponService;


    @Override
    @Transactional
    public OrdersDTO createOrder(Long userId, OrdersDTO ordersDTO, List<OrdersItemsDTO> orderItemsDTOList, List<Long> cartIds) {
        ResponseResult rr = idGeneratorApi.getNextId();
        if (rr.getCode() == 0) {
            throw new RuntimeException("获取id失败");
        }
        // 关键改动：将返回的数据强转为 List<Long> 类型
        Long orderId = Long.parseLong(rr.getData().toString());

        // 优惠券id
        Long userCouponId = ordersDTO.getCouponId();
        // 查询此优惠券是否绑定了订单id
        Long isorderIdBand = userCouponsMapper.selectById(userCouponId).getOrderId();
        if(isorderIdBand != null && isorderIdBand != orderId){
            throw new RuntimeException("优惠券已被使用");
        }else {
            //绑定即可
            userCouponsMapper.bindOrderToCoupon(userCouponId, orderId);
        }

        // 2. 将 DTO 转换为实体类，并设置新生成的ID和时间
        Orders orders = new Orders();
        BeanUtils.copyProperties(ordersDTO, orders);
        orders.setOrderId(orderId);
        orders.setOrderStatus(1); // 默认设置为待支付
        orders.setUpdateTime(LocalDateTime.now().toString());
        orders.setUserId(userId);
        // 3. 插入订单主表
        this.save(orders);
        // 4. 处理订单项列表
        if (orderItemsDTOList != null && !orderItemsDTOList.isEmpty()) {
            List<OrderItems> orderItemsList = orderItemsDTOList.stream()
                    .map(itemDTO -> {
                        OrderItems orderItem = new OrderItems();
                        BeanUtils.copyProperties(itemDTO, orderItem);
                        orderItem.setOrderId(orderId);
                        return orderItem;
                    })
                    .collect(Collectors.toList());

            // 调用 OrderItemsService 进行批量插入
            ordersItemsService.saveBatchOrderItems(orderItemsList);
        }

        // 5. 还要删除  cart购物车表中的当前userId的这些被购买的商品的记录
        cartService.removeItemsFromCart(cartIds);

        BeanUtils.copyProperties(orders, ordersDTO);
        return ordersDTO;
    }


    @Override
    public List<OrdersDTO> getOrdersByUserIdAndStatus(Long userId, Integer orderStatus, Integer page, Integer size) {
        // 构建查询条件
        QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userId", userId);

        // 如果传入了订单状态，则添加状态条件
        if (orderStatus != null) {
            queryWrapper.eq("orderStatus", orderStatus);
        }

        // 按更新时间倒序排列
        queryWrapper.orderByDesc("updateTime");

        // 分页查询
        Page<Orders> pageParam = new Page<>(page, size);
        Page<Orders> ordersPage = this.page(pageParam, queryWrapper);

        // 将 Orders 实体转换为 OrdersDTO 并补充商品明细
        List<OrdersDTO> ordersDTOList = ordersPage.getRecords().stream()
                .map(orders -> {
                    OrdersDTO ordersDTO = new OrdersDTO();
                    BeanUtils.copyProperties(orders, ordersDTO);

                    // ⭐ 关键步骤：为每个订单查询商品明细
                    List<OrdersItemsDTO> orderItems = getOrderItemsWithProductInfo(orders.getOrderId());
                    ordersDTO.setOrderItems(orderItems);

                    // ⭐ 计算订单汇总信息
                    if (orderItems != null && !orderItems.isEmpty()) {
                        // 计算总金额
                        double totalAmount = orderItems.stream()
                                .mapToDouble(item -> item.getPrice() * item.getQuantity())
                                .sum();
                        ordersDTO.setTotalAmount(totalAmount);

                        // 计算总数量
                        int totalQuantity = orderItems.stream()
                                .mapToInt(OrdersItemsDTO::getQuantity)
                                .sum();
                        ordersDTO.setTotalQuantity(totalQuantity);
                    } else {
                        ordersDTO.setTotalAmount(0.0);
                        ordersDTO.setTotalQuantity(0);
                    }

                    return ordersDTO;
                })
                .collect(Collectors.toList());

        return ordersDTOList;
    }

    /**
     * 根据订单ID查询订单商品明细，并补充商品信息
     *
     * @param orderId 订单ID
     * @return 包含商品信息的订单明细列表
     */
    private List<OrdersItemsDTO> getOrderItemsWithProductInfo(Long orderId) {
        // 1. 查询订单商品明细
        QueryWrapper<OrderItems> itemsWrapper = new QueryWrapper<>();
        itemsWrapper.eq("orderId", orderId);
        List<OrderItems> orderItemsList = orderItemsService.list(itemsWrapper);

        if (orderItemsList == null || orderItemsList.isEmpty()) {
            return new ArrayList<>();
        }

        // 2. 转换为DTO并补充商品信息
        return orderItemsList.stream()
                .map(orderItem -> {
                    OrdersItemsDTO dto = new OrdersItemsDTO();
                    BeanUtils.copyProperties(orderItem, dto);

                    // ⭐ 使用ProductService查询商品信息
                    try {
                        ProductDTO productDTO = productService.getProductById(orderItem.getProductId());
                        if (productDTO != null) {
                            dto.setProductName(productDTO.getProductName());
                            dto.setMainImage(productDTO.getMainImage());
                            dto.setDetail(productDTO.getDetail());
                        } else {
                            // 商品可能已被删除，设置默认值
                            dto.setProductName("商品已下架");
                            dto.setMainImage("");
                            dto.setDetail("该商品已不存在");
                        }
                    } catch (Exception e) {
                        // 查询商品信息失败时的容错处理
                        log.warn("查询商品信息失败，商品ID:"+ orderItem.getProductId()+"\n+Exception："+ e);
                        dto.setProductName("商品信息获取失败");
                        dto.setMainImage("");
                        dto.setDetail("");
                    }

                    return dto;
                })
                .collect(Collectors.toList());
    }

    @Override
    public OrdersDTO getOrderById(Long orderId) {
        // 1. 查询订单基本信息
        Orders order = this.getById(orderId);
        if (order == null) {
            return null;
        }

        // 2. 转换为DTO
        OrdersDTO ordersDTO = new OrdersDTO();
        BeanUtils.copyProperties(order, ordersDTO);

        // 3. 查询订单项信息
        QueryWrapper<OrderItems> itemsWrapper = new QueryWrapper<>();
        itemsWrapper.eq("orderId", orderId);
        List<OrderItems> orderItemsList = orderItemsService.list(itemsWrapper);

        // 4. 转换订单项并补充商品信息
        if (orderItemsList != null && !orderItemsList.isEmpty()) {
            List<OrdersItemsDTO> orderItemsDTOList = orderItemsList.stream()
                    .map(orderItem -> {
                        OrdersItemsDTO dto = new OrdersItemsDTO();
                        BeanUtils.copyProperties(orderItem, dto);

                        // 查询商品信息
                        try {
                            ProductDTO productDTO = productService.getProductById(orderItem.getProductId());
                            if (productDTO != null) {
                                dto.setProductName(productDTO.getProductName());
                                dto.setMainImage(productDTO.getMainImage());
                                dto.setDetail(productDTO.getDetail());
                            }
                        } catch (Exception e) {
                            log.warn("查询商品信息失败，商品ID: {}"+ orderItem.getProductId()+ e);
                        }

                        return dto;
                    })
                    .collect(Collectors.toList());

            ordersDTO.setOrderItems(orderItemsDTOList);

            // 优惠券处理
            //查询优惠券表，通过订单id获取是否使用了优惠券
            UserCoupons userCoupons = null;
            if (orderId != null) {
                //查询优惠券表，通过订单id获取是否使用了优惠券
                userCoupons = userCouponsMapper.selectByOrderId(orderId);
                if (userCoupons == null) {
                    log.debug("未使用优惠券");
                }
            }
            // 根据id查询优惠券的减免价格
            BigDecimal couponAmount = BigDecimal.ZERO;
            if (userCoupons != null) {
                couponAmount = couponService.getCouponDetail(userCoupons.getCouponId()).getDiscountAmount();
            }


            // 5. 计算订单总金额和总数量
            double totalAmount = (orderItemsDTOList.stream()
                    .mapToDouble(item -> item.getPrice() * item.getQuantity())
                    .sum())-couponAmount.doubleValue();
            int totalQuantity = orderItemsDTOList.stream()
                    .mapToInt(OrdersItemsDTO::getQuantity)
                    .sum();

            ordersDTO.setTotalAmount(totalAmount);
            ordersDTO.setTotalQuantity(totalQuantity);
        } else {
            ordersDTO.setOrderItems(new ArrayList<>());
            ordersDTO.setTotalAmount(0.0);
            ordersDTO.setTotalQuantity(0);
        }

        return ordersDTO;
    }

    /**
     * 取消订单
     */
    @Override
    @Transactional
    public Boolean cancelOrder(Long orderId) {
        try {
            Orders order = this.getById(orderId);
            if (order == null) {
                throw new RuntimeException("订单不存在");
            }

            // 只有待支付状态的订单可以取消
            if (!order.getOrderStatus().equals(1)) {
                throw new RuntimeException("订单状态不允许取消");
            }

            // 更新订单状态为已取消(0)
            order.setOrderStatus(0);
            order.setUpdateTime(LocalDateTime.now().toString());

            return this.updateById(order);
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            log.error("取消订单失败，订单ID: "+orderId);
            throw new RuntimeException("取消订单失败");
        }
    }

    /**
     * 确认收货
     */
    @Override
    @Transactional
    public Boolean confirmReceipt(Long orderId) {
        try {
            Orders order = this.getById(orderId);
            if (order == null) {
                throw new RuntimeException("订单不存在");
            }

            // 只有已发货状态的订单可以确认收货
            if (!order.getOrderStatus().equals(3)) {
                throw new RuntimeException("订单状态不允许确认收货");
            }

            // 更新订单状态为已签收(4)
            order.setOrderStatus(4);
            order.setUpdateTime(LocalDateTime.now().toString());

            return this.updateById(order);
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            log.error("确认收货失败，订单ID: {}"+ orderId, e);
            throw new RuntimeException("确认收货失败");
        }
    }

    @Override
    public IPage<OrdersDTO> getAllOrders(Integer page, Integer size,
                                         Long orderId, Long userId, Integer orderStatus,
                                         LocalDateTime paymentStartTime, LocalDateTime paymentEndTime,
                                         LocalDateTime shippingStartTime, LocalDateTime shippingEndTime) {
        // 1. 创建分页对象
        Page<Orders> ordersPage = new Page<>(page, size);

        // 2. 构建查询条件
        QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();

        // 订单ID筛选
        if (orderId != null) {
            queryWrapper.eq("orderId", orderId);
        }

        // 用户ID筛选
        if (userId != null) {
            queryWrapper.eq("userId", userId);
        }

        // 订单状态筛选
        if (orderStatus != null) {
            queryWrapper.eq("orderStatus", orderStatus);
        }

        // 支付时间范围筛选
        if (paymentStartTime != null && paymentEndTime != null) {
            queryWrapper.between("paymentTime", paymentStartTime, paymentEndTime);
        } else if (paymentStartTime != null) {
            queryWrapper.ge("paymentTime", paymentStartTime);
        } else if (paymentEndTime != null) {
            queryWrapper.le("paymentTime", paymentEndTime);
        }

        // 发货时间范围筛选
        if (shippingStartTime != null && shippingEndTime != null) {
            queryWrapper.between("shippingTime", shippingStartTime, shippingEndTime);
        } else if (shippingStartTime != null) {
            queryWrapper.ge("shippingTime", shippingStartTime);
        } else if (shippingEndTime != null) {
            queryWrapper.le("shippingTime", shippingEndTime);
        }

        // 按最新操作时间倒序排列
        queryWrapper.orderByDesc("updateTime");

        // 3. 分页查询订单
        this.page(ordersPage, queryWrapper);
        List<Orders> ordersList = ordersPage.getRecords();

        if (ordersList == null || ordersList.isEmpty()) {
            // 返回空的分页结果，但保留分页信息
            Page<OrdersDTO> emptyPage = new Page<>(page, size);
            emptyPage.setTotal(ordersPage.getTotal());
            emptyPage.setRecords(new ArrayList<>());
            return emptyPage;
        }

        // 4. 批量查询所有订单项和商品信息
        List<Long> orderIds = ordersList.stream().map(Orders::getOrderId).collect(Collectors.toList());

        QueryWrapper<OrderItems> itemsWrapper = new QueryWrapper<>();
        itemsWrapper.in("orderId", orderIds);
        List<OrderItems> orderItemsList = orderItemsService.list(itemsWrapper);

        List<Long> productIds = orderItemsList.stream().map(OrderItems::getProductId).distinct().collect(Collectors.toList());

        Map<Long, Product> productMap = new HashMap<>();
        if (!productIds.isEmpty()) {
            List<Product> productList = productMapper.selectByIds(productIds);
            productMap = productList.stream()
                    .collect(Collectors.toMap(Product::getProductId, Function.identity()));
        }

        // 5. 组装订单数据
        Map<Long, OrdersDTO> ordersDTOMap = ordersList.stream()
                .map(order -> {
                    OrdersDTO dto = new OrdersDTO();
                    BeanUtils.copyProperties(order, dto);
                    dto.setOrderId(order.getOrderId()); // 注意：将数据库的id字段映射为orderId
                    dto.setOrderItems(new ArrayList<>());
                    dto.setAddress(addressService.getAddressById(dto.getAddressId()));
                    return dto;
                })
                .collect(Collectors.toMap(OrdersDTO::getOrderId, Function.identity()));

        // 6. 填充订单项和商品信息，并计算总价
        for (OrderItems orderItem : orderItemsList) {
            Long orderId_item = orderItem.getOrderId();
            OrdersDTO ordersDTO = ordersDTOMap.get(orderId_item);

            if (ordersDTO != null) {
                OrdersItemsDTO dto = new OrdersItemsDTO();
                BeanUtils.copyProperties(orderItem, dto);

                Product product = productMap.get(orderItem.getProductId());
                if (product != null) {
                    dto.setProductName(product.getProductName());
                    dto.setMainImage(product.getMainImage());
                    dto.setDetail(product.getDetail());
                } else {
                    log.warn("查询商品信息失败，商品ID: {}"+orderItem.getProductId());
                }

                ordersDTO.getOrderItems().add(dto);
                ordersDTO.setTotalAmount(ordersDTO.getTotalAmount() + (dto.getPrice() * dto.getQuantity()));
                ordersDTO.setTotalQuantity(ordersDTO.getTotalQuantity() + dto.getQuantity());
            }
        }

        // 7. 创建返回的分页对象
        Page<OrdersDTO> resultPage = new Page<>(page, size);
        resultPage.setTotal(ordersPage.getTotal());  // 设置总记录数
        resultPage.setRecords(new ArrayList<>(ordersDTOMap.values()));  // 设置当前页数据

        return resultPage;
    }


    @Override
    @Transactional
    public OrdersDTO updateOrderStatus(Long orderId, Integer newStatus) {
        // 1. 查询订单是否存在
        Orders order = this.getById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }

        // 2. 验证状态转换是否合法（可以根据你的业务需求添加更多验证）
        if (!isValidStatusTransition(order.getOrderStatus(), newStatus)) {
            throw new RuntimeException("非法的状态转换");
        }

        // 3. 更新订单状态
        order.setOrderStatus(newStatus);   //更改订单状态
        order.setUpdateTime(LocalDateTime.now().toString());  //更改最新操作时间
        order.setPaymentTime(LocalDateTime.now().toString());   // 添加付款时间

        // 4. 保存更新
        boolean updated = this.updateById(order);
        if (!updated) {
            throw new RuntimeException("更新订单状态失败");
        }

        // 5. 转换为DTO并返回
        return convertToDTO(order);
    }

    /**
     * 验证订单状态转换是否合法
     */
    private boolean isValidStatusTransition(Integer currentStatus, Integer newStatus) {
        // 这里可以根据你的业务需求添加具体的状态转换规则
        // 例如：
        if (currentStatus == OrderStatus.PENDING_PAYMENT.getCode()) {
            // 待支付状态可以转换为：已支付待发货、已取消
            return newStatus == OrderStatus.PAID_PENDING_SHIP.getCode()
                    || newStatus == OrderStatus.CANCELLED.getCode();
        }
        // ... 其他状态转换规则

        return true; // 如果不需要特别的验证，可以直接返回true
    }

    /**
     * 将Orders实体转换为OrdersDTO
     */
    private OrdersDTO convertToDTO(Orders order) {
        if (order == null) {
            return null;
        }

        OrdersDTO dto = new OrdersDTO();
        BeanUtils.copyProperties(order, dto);
        return dto;
    }
}